// ----------------------------------------
// Filename: Analog.c
// Description: Routines to implement ADC
// Author: Anton Jatmiko
// Date: 29-May-14

#include "Analog.h"

// ----------------------------------------
// Analog_Init
//
// Initialise ADC and its peripheral
// Input:
//   none
// Output:
//   none
// Conditions:
//   none
void Analog_Init(void)
{
    TRISAbits.RA3 = 1;              // Set ch3 to input
    ADCON0bits.ADON = 0;            // Disable A/D Converter
    ADCON1bits.PCFG = 11;           // Set AN3,2,1,0 to analog
    ADCON0bits.CHS = 3;             // Select analog ch3
    ADCON1bits.VCFG0 = 0;           // VDD
    ADCON1bits.VCFG1 = 0;           // VSS
    ADCON2bits.ADFM = 1;            // Right justified
    //ADCON2bits.ADCS = 1;            // Fosc/8
    ADCON2bits.ADCS = 4;            // Fosc/4
    //ADCON2bits.ACQT = 7;            // 20 Tad
    ADCON2bits.ACQT = 2;            // 4 Tad
    ADCON0bits.ADON = 1;            // Enable A/D Converter

    PIR1bits.ADIF = 0;
    PIE1bits.ADIE = 0;              // Disable A/D Interrupt
    IPR1bits.ADIP = 1;
}

// ----------------------------------------
// Analog_StartSampling
//
// Initialise ADC and its peripheral
// Input:
//   enable is a boolean indicates whether to start ADC conversion
// Output:
//   none
// Conditions:
//   ADC has been initialised
void Analog_StartSampling(BOOL enable)
{
    ADCON0bits.GO_DONE = enable;
}

// ----------------------------------------
// Analog_Read
//
// Read the ADC conversion result
// Input:
//   dataPtr is a pointer to the variable to store raw data
// Output:
//   none
// Conditions:
//   assume raw data is ready
void Analog_Read(TUINT16 * const dataPtr)
{
    dataPtr->l = ADRES;
}

// ----------------------------------------
// Analog_Temperature
//
// Convert raw data to Celcius * 10
// Input:
//   dataPtr is a pointer to the temperature variable
// Output:
//   none
// Conditions:
//   none
void Analog_Temperature(TUINT16 * const dataPtr)
{
    UINT32 temperature;
    TUINT16 rawPtr;
    Analog_Read(&rawPtr);
    temperature = ((UINT32) (rawPtr.l) * 3222) / 1000 - 500;
    dataPtr->l = (UINT16) temperature;
}

// ----------------------------------------
// Analog_SetInterrupt
//
// Arm or disarm ADC interrupt
// Input:
//   enable is a boolean indicates whether to arm or disarm ADC interrupt
// Output:
//   none
// Conditions:
//   none
void Analog_SetInterrupt(BOOL enable)
{
    PIE1bits.ADIE = enable;              // Arm or disarm A/D Interrupt
}